/*
 *   Copyright 2011-2012 Hai Bison
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

/*
 * DialogPopupMessages.java
 *
 * Created on Sep 15, 2011, 3:59:54 PM
 */
package group.pals.mailgate;

import group.pals.mailgate.beans.ItemEmailMessage;
import group.pals.mailgate.beans.ItemGroupEmailMessages;
import group.pals.mailgate.media.SoundPlayer;
import group.pals.mailgate.media.SoundPlayerAdapter;
import group.pals.mailgate.threads.EmailReader;
import group.pals.mailgate.ui.EmailMessageCellRenderer;
import group.pals.mailgate.ui.WindowTransformer;
import group.pals.mailgate.preferences.Preferences;
import group.pals.mailgate.preferences.PreferencesAdapter;
import group.pals.mailgate.utils.Utils;
import group.pals.threads.BaseThread;
import group.pals.threads.listeners.ThreadAdapter;
import group.pals.utils.sys.MessageBox;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.mail.Flags.Flag;
import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.Timer;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

/**
 *
 * @author Hai Bison
 */
public final class DialogPopupMessages extends javax.swing.JDialog {

    private final Utils utils;
    private final group.pals.mailgate.ui.Utils utilsUI;
    private final Preferences _Preferences;
    private final DefaultTreeModel TreeModel;
    private final JPopupMenu PopupMenuEmailReaders;
    private final JPopupMenu PopupMenuEmailMessages;
    private final EmailMessageCellRenderer _EmailMessageCellRenderer;
    private final Comparator<ItemEmailMessage> EmailMessagesComparator;
    private final Timer AutoHideTimer;
    private final SoundPlayer _SoundPlayer;
    private WindowTransformer windowTransformer;
    private boolean userIsWorking;

    /** Creates new form DialogPopupMessages */
    public DialogPopupMessages(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();

        this.utils = Utils.getInstance();
        this.utilsUI = group.pals.mailgate.ui.Utils.getInstance();
        this._Preferences = Preferences.getInstance();
        this.TreeModel = new DefaultTreeModel(new DefaultMutableTreeNode());
        this.PopupMenuEmailReaders = new JPopupMenu();
        this.PopupMenuEmailMessages = new JPopupMenu();

        this._EmailMessageCellRenderer = new EmailMessageCellRenderer();
        ImageIcon icon32 = utils.getIcon(32);
        this._EmailMessageCellRenderer.setOpenIcon(icon32);
        this._EmailMessageCellRenderer.setClosedIcon(icon32);

        this._EmailMessageCellRenderer.setPanelEmailMessagePaddingWidth(_Preferences.getPopupWindowPaddingWidth());
        this.EmailMessagesComparator = new Comparator<ItemEmailMessage>() {

            public int compare(ItemEmailMessage o1, ItemEmailMessage o2) {
                return -(o1.getReceivedDate().compareTo(o2.getReceivedDate()));
            }
        };

        this.AutoHideTimer = new Timer(_Preferences.getPopupWindowDelayTime(), new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                if (!userIsWorking) {
                    setVisible(false);
                }
            }
        });
        this.AutoHideTimer.setRepeats(false);

        this._SoundPlayer = SoundPlayer.getInstance();

        this.windowTransformer = null;

        this.userIsWorking = false;

        initUI();
        initActions();
        initListeners();
    }

    private void initUI() {
        toolBarMain.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
        toolBarMain.setVisible(false);

        setIconImages(utils.getMainIcons());

        setVisible(false);
        setResizable(false);
        setTitle(utils.getAppTitleWithVersion());

        Rectangle desktopSize = utilsUI.getDesktopSize();
        setBounds(desktopSize.width - _Preferences.getPopupWindowWidth() + desktopSize.x,
                desktopSize.height - _Preferences.getPopupWindowHeight() + desktopSize.y,
                _Preferences.getPopupWindowWidth(), _Preferences.getPopupWindowHeight());
        setAlwaysOnTop(true);
        setDefaultCloseOperation(javax.swing.JFrame.HIDE_ON_CLOSE);

        addWindowListener(new WindowAdapter() {

            private void stopAutoHideTimerAndHide() {
                userIsWorking = false;
                if (AutoHideTimer.isRunning()) {
                    AutoHideTimer.stop();
                }
                setVisible(false);
            }

            @Override
            public void windowClosing(WindowEvent e) {
                stopAutoHideTimerAndHide();
            }

            @Override
            public void windowIconified(WindowEvent e) {
                stopAutoHideTimerAndHide();
            }

            @Override
            public void windowActivated(WindowEvent e) {
                userIsWorking = true;
            }

            @Override
            public void windowDeactivated(WindowEvent e) {
                userIsWorking = false;
                if (!AutoHideTimer.isRunning()) {
                    setVisible(false);
                }
            }
        });

        //tree messages
        treeMessages.setModel(TreeModel);
        treeMessages.setCellRenderer(_EmailMessageCellRenderer);
        treeMessages.setRootVisible(false);

        treeMessages.addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent e) {
                if (e.isPopupTrigger()) {
                    handlePopupTriggerEvent(e);
                }
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                if (e.isPopupTrigger()) {
                    handlePopupTriggerEvent(e);
                }
            }

            private void handlePopupTriggerEvent(MouseEvent e) {
                TreePath path = treeMessages.getClosestPathForLocation(e.getX(), e.getY());
                if (path == null || !(path.getLastPathComponent() instanceof DefaultMutableTreeNode)) {
                    return;
                }

                DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
                if (node.getUserObject() instanceof ItemEmailMessage) {
                    PopupMenuEmailMessages.show(treeMessages, e.getX(), e.getY());
                } else if (node.getUserObject() instanceof EmailReader) {
                    PopupMenuEmailReaders.show(treeMessages, e.getX(), e.getY());
                }
            }
        });//mouse listener
    }

    public void initActions() {
        //action for sound controller
        actionStopSound = new ActionStopSound();
        buttonStopSound.setAction(actionStopSound);

        //actions for e-mail readers
        actionCheckEmailAccountsNow = new ActionCheckEmailAccountsNow();
        actionCheckAllEmailAccountsNow = new ActionCheckAllEmailAccountsNow();

        JMenuItem miCheckEmailAccountNow = new JMenuItem(actionCheckEmailAccountsNow);
        PopupMenuEmailReaders.add(miCheckEmailAccountNow);
        JMenuItem miCheckAllEmailAccountsNow = new JMenuItem(actionCheckAllEmailAccountsNow);
        PopupMenuEmailReaders.add(miCheckAllEmailAccountsNow);

        //actions for e-mail messages
        actionMarkEmailMessagesAsSpam = new ActionMarkEmailMessagesAsSpam();
        actionMarkEmailMessagesAsRead = new ActionMarkEmailMessagesAsRead();
        actionDeleteEmailMessages = new ActionDeleteEmailMessages();

        JMenuItem miMarkEmailMessageAsSpam = new JMenuItem(actionMarkEmailMessagesAsSpam);
        PopupMenuEmailMessages.add(miMarkEmailMessageAsSpam);
        JMenuItem miMarkEmailMessageAsRead = new JMenuItem(actionMarkEmailMessagesAsRead);
        PopupMenuEmailMessages.add(miMarkEmailMessageAsRead);
        JMenuItem miDeleteEmailMessage = new JMenuItem(actionDeleteEmailMessages);
        PopupMenuEmailMessages.add(miDeleteEmailMessage);
    }

    private void initListeners() {
        _Preferences.addPreferencesListener(new PreferencesAdapter() {

            @Override
            public void preferencesStored() {
                if (_SoundPlayer.isPlaying()) {
                    _SoundPlayer.stop();
                }
                if (isVisible()) {
                    updatePosition();
                }
            }
        });

        _SoundPlayer.addSoundPlayerListener(new SoundPlayerAdapter() {

            @Override
            public void soundPlay(SoundPlayer sender) {
                toolBarMain.setVisible(true);
                actionStopSound.setEnabled(true);
            }

            @Override
            public void soundStop(SoundPlayer sender) {
                toolBarMain.setVisible(false);
                actionStopSound.setEnabled(false);
            }
        });
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        toolBarMain = new javax.swing.JToolBar();
        buttonStopSound = new javax.swing.JButton();
        scrollPaneTreeMessages = new javax.swing.JScrollPane();
        treeMessages = new javax.swing.JTree();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setUndecorated(true);
        getContentPane().setLayout(new java.awt.GridBagLayout());

        toolBarMain.setBorder(javax.swing.BorderFactory.createMatteBorder(1, 1, 1, 1, new java.awt.Color(102, 0, 0)));
        toolBarMain.setFloatable(false);
        toolBarMain.setRollover(true);

        buttonStopSound.setText("jButton1");
        buttonStopSound.setFocusable(false);
        buttonStopSound.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        buttonStopSound.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        toolBarMain.add(buttonStopSound);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        getContentPane().add(toolBarMain, gridBagConstraints);

        javax.swing.tree.DefaultMutableTreeNode treeNode1 = new javax.swing.tree.DefaultMutableTreeNode("root");
        treeMessages.setModel(new javax.swing.tree.DefaultTreeModel(treeNode1));
        scrollPaneTreeMessages.setViewportView(treeMessages);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        getContentPane().add(scrollPaneTreeMessages, gridBagConstraints);

        pack();
    }// </editor-fold>//GEN-END:initComponents
    /**
     * @param args the command line arguments
     */
//  public static void main(String args[]) {
//    /* Set the Nimbus look and feel */
//    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
//        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
//     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
//     */
//    try {
//      for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
//        if ("Nimbus".equals(info.getName())) {
//          javax.swing.UIManager.setLookAndFeel(info.getClassName());
//          break;
//        }
//      }
//    } catch (ClassNotFoundException ex) {
//      java.util.logging.Logger.getLogger(DialogPopupMessages.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
//    } catch (InstantiationException ex) {
//      java.util.logging.Logger.getLogger(DialogPopupMessages.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
//    } catch (IllegalAccessException ex) {
//      java.util.logging.Logger.getLogger(DialogPopupMessages.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
//    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
//      java.util.logging.Logger.getLogger(DialogPopupMessages.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
//    }
//    //</editor-fold>
//
//    /* Create and display the dialog */
//    java.awt.EventQueue.invokeLater(new Runnable() {
//
//      public void run() {
//        DialogPopupMessages dialog = new DialogPopupMessages(new javax.swing.JFrame(), true);
//        dialog.addWindowListener(new java.awt.event.WindowAdapter() {
//
//          @Override
//          public void windowClosing(java.awt.event.WindowEvent e) {
//            System.exit(0);
//          }
//        });
//        dialog.setVisible(true);
//      }
//    });
//  }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton buttonStopSound;
    private javax.swing.JScrollPane scrollPaneTreeMessages;
    private javax.swing.JToolBar toolBarMain;
    private javax.swing.JTree treeMessages;
    // End of variables declaration//GEN-END:variables

    public void updateEmails(EmailReader emailReader, List<ItemEmailMessage> emailMessages) {
        _EmailMessageCellRenderer.setPanelEmailMessagePaddingWidth(_Preferences.getPopupWindowPaddingWidth());

        if (_Preferences.isGroupEmailsByConversation()) {
            List<ItemEmailMessage> tmp = new ArrayList<ItemEmailMessage>();
            List<ItemGroupEmailMessages> groupEmailMessages =
                    group.pals.mailgate.beans.Utils.getInstance().groupEmailMessagesByConversation(emailMessages);
            for (ItemGroupEmailMessages gem : groupEmailMessages) {
                tmp.add(gem.getNewestMessage());
            }
            emailMessages.clear();
            emailMessages.addAll(tmp);
        }

        Collections.sort(emailMessages, EmailMessagesComparator);

        //check if there is current e-mail reader
        DefaultMutableTreeNode nodeEmailReader = null;
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) TreeModel.getRoot();
        for (int i = 0; i < root.getChildCount(); i++) {
            DefaultMutableTreeNode node = (DefaultMutableTreeNode) root.getChildAt(i);
            if (emailReader.equals(node.getUserObject())) {
                node.removeAllChildren();
                TreeModel.reload(node);
                nodeEmailReader = node;
                break;
            }
        }

        //if not, create new node
        if (nodeEmailReader == null) {
            if (emailMessages.isEmpty()) {
                return;
            }
            nodeEmailReader = new DefaultMutableTreeNode(emailReader, true);
            TreeModel.insertNodeInto(nodeEmailReader, root, root.getChildCount());
        } else {
            if (emailMessages.isEmpty()) {
                TreeModel.removeNodeFromParent(nodeEmailReader);
                return;
            }
        }

        for (ItemEmailMessage emailMessage : emailMessages) {
            DefaultMutableTreeNode item = new DefaultMutableTreeNode(emailMessage);
            TreeModel.insertNodeInto(item, nodeEmailReader, nodeEmailReader.getChildCount());
            nodeEmailReader.add(item);
        }

        //reload tree
        TreeModel.reload();

        //expand nodes
        TreePath treePath = new TreePath(root.getPath());
        treeMessages.expandPath(treePath);
        treePath = new TreePath(nodeEmailReader.getPath());
        treeMessages.expandPath(treePath);
        treeMessages.setSelectionPath(treePath);

        //scroll nodeEmailReader to top
        Rectangle pathBounds = treeMessages.getPathBounds(treePath);
        if (pathBounds != null) {
            //first, scroll the node to visible view
            treeMessages.scrollRectToVisible(pathBounds);
            //second, scroll the node to the top of view
            pathBounds.height = treeMessages.getHeight();
            treeMessages.scrollRectToVisible(pathBounds);
        }
    }

    public synchronized void clearAllEmailReaders() {
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) TreeModel.getRoot();
        root.removeAllChildren();
        TreeModel.reload();
    }

    public void updatePosition() {
        Rectangle desktopSize = utilsUI.getDesktopSize();
        Dimension winSize = getSize();
        winSize.width = _Preferences.getPopupWindowWidth();
        winSize.height = _Preferences.getPopupWindowHeight();

        //default fromLocation is location #2 (center)
        Point fromLocation = new Point((desktopSize.width - winSize.width) / 2 + desktopSize.x,
                (desktopSize.height - winSize.height) / 2 + desktopSize.y);

        //default toLocation is location #0 (top-left)
        Point toLocation = new Point(desktopSize.x, desktopSize.y);

        switch (_Preferences.getPopupWindowPosition()) {
            case 0: {
                break;
            }
            case 1: {
                toLocation.x = desktopSize.width - winSize.width + desktopSize.x;
                break;
            }
            case 2: {
                toLocation.x = fromLocation.x;
                toLocation.y = fromLocation.y;
                fromLocation.x = desktopSize.x;
                fromLocation.y = desktopSize.y;
                break;
            }
            case 3: {
                toLocation.y = desktopSize.height - winSize.height + desktopSize.y;
                break;
            }
            default: {
                toLocation.x = desktopSize.width - winSize.width + desktopSize.x;
                toLocation.y = desktopSize.height - winSize.height + desktopSize.y;
                break;
            }
        }

        if (_Preferences.isPopupWindowAnimationOn()) {
            setBounds(fromLocation.x, fromLocation.y, winSize.width, winSize.height);

            if (windowTransformer != null) {
                windowTransformer.interrupt();
            }
            windowTransformer = new WindowTransformer(this, fromLocation, toLocation, 500);
            windowTransformer.addThreadListener(new ThreadAdapter() {

                @Override
                public void threadTerminated(BaseThread sender) {
                    windowTransformer = null;
                }
            });
            windowTransformer.start();
        } else {
            setBounds(toLocation.x, toLocation.y, winSize.width, winSize.height);
        }
    }

    public void popup() {
        if (!isVisible()) {
            setVisible(true);
        }
        toFront();
        requestFocus();
        updatePosition();

        AutoHideTimer.setInitialDelay(_Preferences.getPopupWindowDelayTime());
        if (AutoHideTimer.isRunning()) {
            AutoHideTimer.stop();
        }
        AutoHideTimer.start();
    }

    /**
     * Gets e-mail reader.
     * @param all if <code>true</code>, gets all. Otherwise, gets selected ones.
     * @return 
     */
    private List<EmailReader> getEmailReaders(boolean all) {
        List<EmailReader> result = new ArrayList<EmailReader>();

        DefaultMutableTreeNode root = (DefaultMutableTreeNode) TreeModel.getRoot();
        for (Enumeration<DefaultMutableTreeNode> nodes = root.children(); nodes.hasMoreElements();) {
            DefaultMutableTreeNode node = nodes.nextElement();
            if (all || treeMessages.isPathSelected(new TreePath(node.getPath()))) {
                result.add((EmailReader) node.getUserObject());
            }
        }

        return result;
    }

    private Map<EmailReader, List<ItemEmailMessage>> getMapSelectedEmailMessages() {
        Map<EmailReader, List<ItemEmailMessage>> result = new HashMap<EmailReader, List<ItemEmailMessage>>();

        DefaultMutableTreeNode root = (DefaultMutableTreeNode) TreeModel.getRoot();
        for (Enumeration<DefaultMutableTreeNode> nodeEmailReaders = root.children(); nodeEmailReaders.hasMoreElements();) {
            DefaultMutableTreeNode nodeEmailReader = nodeEmailReaders.nextElement();
            List<ItemEmailMessage> emailMessages = new ArrayList<ItemEmailMessage>();

            for (Enumeration<DefaultMutableTreeNode> nodeEmailMessages = nodeEmailReader.children(); nodeEmailMessages.hasMoreElements();) {
                DefaultMutableTreeNode nodeEmailMessage = nodeEmailMessages.nextElement();
                if (treeMessages.isPathSelected(new TreePath(nodeEmailMessage.getPath()))) {
                    emailMessages.add((ItemEmailMessage) nodeEmailMessage.getUserObject());
                }
            }

            if (!emailMessages.isEmpty()) {
                result.put((EmailReader) nodeEmailReader.getUserObject(), emailMessages);
            }
        }

        return result;
    }

    private void markSelectedEmailMessagesAndForceCheck(
            Map<EmailReader, List<ItemEmailMessage>> mapSelectedEmailMessages, Flag flag, boolean value) {
        for (EmailReader emailReader : mapSelectedEmailMessages.keySet()) {
            List<ItemEmailMessage> emailMessages = mapSelectedEmailMessages.get(emailReader);
            for (ItemEmailMessage emailMessage : emailMessages) {
                emailMessage.setFlag(flag, value);
            }
        }

        for (EmailReader emailReader : mapSelectedEmailMessages.keySet()) {
            emailReader.doForceCheck();
        }
    }

    /*----------------------------------------------------------------------------
     * popupMenuEmailMessages' actions
     */

    /*----------------------------------------------------------------------------
     * ActionMarkAsSpam
     */
    private ActionMarkEmailMessagesAsSpam actionMarkEmailMessagesAsSpam;

    private class ActionMarkEmailMessagesAsSpam extends AbstractAction {

        public ActionMarkEmailMessagesAsSpam() {
            super("Mark as spam");
        }

        public void actionPerformed(ActionEvent e) {
            MessageBox.showInfoMsg(null, null, "Under construction  :-)");
        }
    }

    /*----------------------------------------------------------------------------
     * ActionMarkAsRead
     */
    private ActionMarkEmailMessagesAsRead actionMarkEmailMessagesAsRead;

    private class ActionMarkEmailMessagesAsRead extends AbstractAction {

        public ActionMarkEmailMessagesAsRead() {
            super("Mark as read");
        }

        public void actionPerformed(ActionEvent e) {
            Map<EmailReader, List<ItemEmailMessage>> map = getMapSelectedEmailMessages();
            if (map.isEmpty()) {
                MessageBox.showInfoMsg(null, null, "Please select e-mails to mark");
                return;
            }

            markSelectedEmailMessagesAndForceCheck(map, Flag.SEEN, true);
        }
    }

    /*----------------------------------------------------------------------------
     * ActionDeleteEmail
     */
    private ActionDeleteEmailMessages actionDeleteEmailMessages;

    private class ActionDeleteEmailMessages extends AbstractAction {

        public ActionDeleteEmailMessages() {
            super("Delete");
        }

        public void actionPerformed(ActionEvent e) {
            Map<EmailReader, List<ItemEmailMessage>> map = getMapSelectedEmailMessages();
            if (map.isEmpty()) {
                MessageBox.showInfoMsg(null, null, "Please select e-mails to delete");
                return;
            }

            if (MessageBox.confirmYesNo(null, null, "Are you sure you want to delete selected e-mail(s)?", 1)) {
                markSelectedEmailMessagesAndForceCheck(map, Flag.DELETED, true);
            }
        }
    }

    /*----------------------------------------------------------------------------
     * popupMenuEmailReaders' actions
     */

    /*----------------------------------------------------------------------------
     * ActionCheckEmailAccountsNow
     */
    private ActionCheckEmailAccountsNow actionCheckEmailAccountsNow;

    private class ActionCheckEmailAccountsNow extends AbstractAction {

        public ActionCheckEmailAccountsNow() {
            super("Check now");
        }

        public void actionPerformed(ActionEvent e) {
            List<EmailReader> emailReaders = getEmailReaders(false);
            if (emailReaders.isEmpty()) {
                MessageBox.showInfoMsg(null, null, "Please select account(s) to check");
            } else {
                for (EmailReader emailReader : emailReaders) {
                    emailReader.doForceCheck();
                }
            }
        }
    }

    /*----------------------------------------------------------------------------
     * ActionCheckAllEmailAccountsNow
     */
    private ActionCheckAllEmailAccountsNow actionCheckAllEmailAccountsNow;

    private class ActionCheckAllEmailAccountsNow extends AbstractAction {

        public ActionCheckAllEmailAccountsNow() {
            super("Check all now");
        }

        public void actionPerformed(ActionEvent e) {
            List<EmailReader> emailReaders = getEmailReaders(true);
            if (emailReaders.isEmpty()) {
                MessageBox.showInfoMsg(null, null, "There is no account to check");
            } else {
                for (EmailReader emailReader : emailReaders) {
                    emailReader.doForceCheck();
                }
            }
        }
    }

    /*----------------------------------------------------------------------------
     * ActionStopSound
     */
    private ActionStopSound actionStopSound;

    private class ActionStopSound extends AbstractAction {

        public ActionStopSound() {
            super("Stop sound");
        }

        public void actionPerformed(ActionEvent e) {
            _SoundPlayer.stop();
            setEnabled(false);
        }
    }
}
